﻿// ***********************************************************************
// Assembly         : INNOVACALL.Framework.Common
// Author           : LJO+01 (Laurent Jordi)
// Created          : 06-05-2013
// Last Modified By : LJO+01 (Laurent Jordi)
// Last Modified On : 06-05-2013
// ***********************************************************************
// <copyright file="ViewRenderingToString.cs" company="Copyright © Innovacall 2011">
//     Copyright (c) Copyright © Innovacall 2011. All rights reserved.
// </copyright>
// <summary></summary>
// ***********************************************************************
using System;
using System.IO;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;

namespace INNOVACALL.Framework.Common.MVCHelpers
{
    /// <summary>
    /// http://www.klopfenstein.net/lorenz.aspx/render-partial-view-to-string-in-asp-net-mvc
    /// </summary>
	public static class ViewRenderingToString
	{
        /// <summary>
        /// Renders a view to string.
        /// </summary>
        /// <param name="html">The HTML.</param>
        /// <param name="viewName">Name of the view.</param>
        /// <param name="viewData">The view data.</param>
        /// <returns>System.String.</returns>
		public static string RenderPartialToString(this HtmlHelper html, string viewName, object viewData)
		{
			return RenderViewToString(html.ViewContext.Controller.ControllerContext, viewName, viewData);
		}

        /// <summary>
        /// Renders a view to string.
        /// </summary>
        /// <param name="controller">The controller.</param>
        /// <param name="viewName">Name of the view.</param>
        /// <param name="viewData">The view data.</param>
        /// <returns>System.String.</returns>
		public static string RenderViewToString(this Controller controller, string viewName, object viewData)
		{
			return RenderViewToString(controller.ControllerContext, viewName, viewData);
		}

        /// <summary>
        /// Renders the view to string.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="viewName">Name of the view.</param>
        /// <param name="viewData">The view data.</param>
        /// <returns>System.String.</returns>
		private static string RenderViewToString(ControllerContext context,
												string viewName, object viewData)
		{
			//Create memory writer 
			var sb = new StringBuilder();
			var memWriter = new StringWriter(sb);

			//Create fake http context to render the view 
			var fakeResponse = new HttpResponse(memWriter);
			var fakeContext = new HttpContext(HttpContext.Current.Request, fakeResponse);
			var fakeControllerContext = new ControllerContext(
				new HttpContextWrapper(fakeContext),
				context.RouteData, context.Controller);

			var oldContext = HttpContext.Current;
			HttpContext.Current = fakeContext;

			//Use HtmlHelper to render partial view to fake context 
			var html = new HtmlHelper
			(
				new ViewContext
				(
					fakeControllerContext,
					new FakeView(), 
					new ViewDataDictionary(), 
					new TempDataDictionary(),
					memWriter
				),
				new ViewPage());
			html.RenderPartial(viewName, viewData);

			//Restore context 
			HttpContext.Current = oldContext;

			//Flush memory and return output 
			memWriter.Flush();
			return sb.ToString();
		}
        /// <summary>
        /// Fake IView implementation, only used to instantiate an HtmlHelper.
        /// </summary>
		public class FakeView : IView
		{
			#region IView Members
            /// <summary>
            /// Restitue le contexte d'affichage spécifié à l'aide de l'objet writer spécifié.
            /// </summary>
            /// <param name="viewContext">Contexte d'affichage.</param>
            /// <param name="writer">Objet writer.</param>
            /// <exception cref="System.NotImplementedException"></exception>
			public void Render(ViewContext viewContext, System.IO.TextWriter writer)
			{
				throw new NotImplementedException();
			}
			#endregion
		}		 		 
	}
}
